<?php

/*
 * Camelot PHP Tools
 *
 * @version 2.0
 * @author Bendsoft
 * @package PHP Tools
 * @subpackage Camelot
 * @license FreeBSD License (www.bendsoft.com/licensing/)
 * 
 */

if (!isset($_SESSION)) {
    session_start();
}


class CamelotAuthentication {

    public function __construct() {
        if ($_POST) {
            if (isset($_POST['ntlm_username']) && isset($_POST['ntlm_password'])) {
                $_SESSION['NTLM_CREDENTIALS'] = $_POST;
            }
        }
    }

}

/**
 * Class with functionality to handle commands that support caching
 * @author Bendsoft
 */
class SharePointCommandCache extends CamelotAuthentication {

    /**
     * Retrieves the cached file, if any
     * @param WcfSettingsObject $settings
     * @return string CamelotXML File 
     */
    protected function get_cached_file(WcfSettingsObject $settings) {
        $download = null;

        if ($settings->wsdl_cache > 0) {
            if (file_exists($this->get_cached_file_name($settings))) {

                $fileDateTime = strtotime(date('Y-m-d H:i:s', filemtime($this->get_cached_file_name($settings))));
                $currentDateTime = strtotime(NOW);

                // Check time diff in minutes
                $timeDiff = round(abs($currentDateTime - $fileDateTime) / 60, 2);
                if ($timeDiff < $settings->wsdl_cache) {
                    $download = $this->read_file($this->get_cached_file_name($settings));
                }
            }
        }

        return $download;
    }

    /**
     * Get the correct filename of a cached file
     * @param array $args
     * @return string 
     */
    protected function get_cached_file_name(WcfSettingsObject $settings) {
        // Switch extension based on compression state
        $fileExt = ($settings->compression == 1 || $settings->compression === true || $settings->compression == "true") ? ".cxp" : ".xml";
        return constant("TEMP_DIR") . "/" . md5(serialize($settings)) . $fileExt;
    }

    /**
     * Create a cache file
     * @param string $data
     * @param array $args
     * @return bool|CamelotException
     */
    protected function set_cached_file($data, WcfSettingsObject $settings) {
        // If caching is enabled lets refresh the file
        if ($settings->wsdl_cache > 0) {
            try {
                $fileName = $this->get_cached_file_name($settings);

                $fh = fopen($fileName, 'w');
                fwrite($fh, $data);
                fclose($fh);
                return true;
            } catch (Exception $exc) {
                return new CamelotException($exc);
            }
        }
    }

    /**
     * Read a stored file
     * @param string $fileName
     * @return string
     */
    private function read_file($fileName) {
        $fh = fopen($fileName, 'r');

        // On error
        if ($fh === false) {
            return new CamelotException(null, 410);
        }

        $document = fread($fh, filesize($fileName));
        fclose($fh);
        return $document;
    }

}

/**
 * Base class of SharePoint Commands
 * @author Bendsoft
 */
class SharePointCommandBase extends SharePointCommandCache {

    /**
     * Name of the connection
     * @var string
     */
    public $connection_name;

    /**
     * Currently not implemented (default false)
     * @var bool
     */
    public $includeAttachments;

    /**
     * Method to decode packets
     *
     * @access	private
     * @param string $packet
     * @return	CamelotException|object
     */
    protected function decode_packet($packet) {

        if (!$packet) {
            return new CamelotException(null, 404);
        }

        // check if the packed is base64 encoded, if not it's probably an error returned.
        if (!$this->checkBase64Encoded($packet))
            return $packet;

        $decodedPacket = base64_decode($packet);
        $inflatedPacket = gzinflate($decodedPacket);

        return $inflatedPacket;
    }

    /**
     * Check a string of base64 encoded data to make sure it has actually
     * been encoded.
     *
     * @access Private
     * @param $encodedString string Base64 encoded string to validate.
     * @return Boolean Returns true when the given string only contains
     * base64 characters; returns false if there is even one non-base64 character.
     */
    protected function checkBase64Encoded($encodedString) {
        $length = strlen($encodedString);

        // Check every character.
        for ($i = 0; $i < $length; ++$i) {
            $c = $encodedString[$i];
            if (
                    ($c < '0' || $c > '9')
                    && ($c < 'a' || $c > 'z')
                    && ($c < 'A' || $c > 'Z')
                    && ($c != '+')
                    && ($c != '/')
                    && ($c != '=')
            ) {
                // Bad character found.
                return false;
            }
        }
        // Only good characters found.
        return true;
    }

}

?>
